/**
 * Copyright (C) 2010 Cloudfarming <info@cloudfarming.nl>
 *
 * Licensed under the Eclipse Public License - v 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package nl.cloudfarming.client.sensor.greenseeker;

import java.util.Date;
import java.util.List;
import nl.cloudfarming.client.model.SensorDataFile;
import nl.cloudfarming.client.model.SensorMetadata;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

/**
 *
 * @author Merijn Zengers
 */
public class GreenseekerServiceImplIT {

    GreenseekerServiceImpl service  = new GreenseekerServiceImpl();
    private Log log = LogFactory.getLog(GreenseekerServiceImplIT.class);

    // TEST DATA 1
    private static final Double OBJECTID_1 = 1.000;
    private static final Double LONGITUDE_1 = 7.089869;
    private static final Double LATITUDE_1 = 53.084656;
    private static final Double SPEED_1 = 5.068;
    private static final Double HEADING_1 = 78.000;
    private static final Double ELEVATION_1 = -1.900;
    private static final Double NDVI_1 = 0.794;
    private static final Double VI_2ND_1 = 0.794;
    private static final Double SENSOR_10_1 = 0.818;
    private static final Double SENSOR_19_1 = 0.722;
    private static final Double SENSOR_23_1 = 0.839;
    private static final Double SENSOR_24_1 = 0.870;
    private static final Double SENSOR_26_1 = 0.718;
    private static final Double SENSOR_73_1 = 0.800;
    private static final Double RED_53_1 = 0.018;
    private static final Double NIR_53_1 = 0.035;
    private static final Double RED_54_1 = 0.008;
    private static final Double NIR_54_1 = 0.021;
    private static final Double RED_55_1 = 0.014;
    private static final Double NIR_55_1 = 0.032;
    private static final Double RED_56_1 = 0.022;
    private static final Double NIR_56_1 = 0.046;
    private static final Double RED_57_1 = 0.010;
    private static final Double NIR_57_1 = 0.021;
    private static final Double RED_58_1 = 0.023;
    private static final Double NIR_58_1 = 0.052;
    private static final String FILE_CHECKSUM_1 = "112233aabb";
    private static final String FILE_NAME_1 = "FileName1";
    private static SensorMetadata METADATA_1;
    private static Date DATE_CREATED_1;

    // TEST DATA 2
    private static final Double OBJECTID_2 = 2.000;
    private static final Double LONGITUDE_2 = 8.089869;
    private static final Double LATITUDE_2 = 54.084656;
    private static final Double SPEED_2 = 6.068;
    private static final Double HEADING_2 = 79.000;
    private static final Double ELEVATION_2 = -2.900;
    private static final Double NDVI_2 = 0.894;
    private static final Double VI_2ND_2 = 0.894;
    private static final Double SENSOR_10_2 = 0.918;
    private static final Double SENSOR_19_2 = 0.822;
    private static final Double SENSOR_23_2 = 0.939;
    private static final Double SENSOR_24_2 = 0.970;
    private static final Double SENSOR_26_2 = 0.818;
    private static final Double SENSOR_73_2 = 0.900;
    private static final Double RED_53_2 = 0.028;
    private static final Double NIR_53_2 = 0.045;
    private static final Double RED_54_2 = 0.018;
    private static final Double NIR_54_2 = 0.031;
    private static final Double RED_55_2 = 0.024;
    private static final Double NIR_55_2 = 0.042;
    private static final Double RED_56_2 = 0.032;
    private static final Double NIR_56_2 = 0.056;
    private static final Double RED_57_2 = 0.020;
    private static final Double NIR_57_2 = 0.031;
    private static final Double RED_58_2 = 0.033;
    private static final Double NIR_58_2 = 0.062;
    private static final String FILE_CHECKSUM_2 = "112233aacc";
    private static final String FILE_NAME_2 = "FileName2";
    private static SensorMetadata METADATA_2;
    private static Date DATE_CREATED_2;


    @After
    public void cleantable(){
        for(GreenseekerSensorData sensorData : service.findAllGreenseekerSensorData()){
            service.delete(sensorData);
        }
        for(SensorDataFile dataFile : service.findAllSensorDataFiles()){
            service.removeSensorDataFile(dataFile);
        }
        for(SensorMetadata metadata : service.findAllSensorMetadata()){
            service.remove(metadata);
        }
    }

    @Before
    public void setUp(){
         cleantable();
         METADATA_1 = new SensorMetadata("MMDDYY.CSV", 3, 3, "","","");
         METADATA_2 = new SensorMetadata("MMDDYY.CSV", 5, 3, "","","");
         service.newSensorMetaData(METADATA_1);
         service.newSensorMetaData(METADATA_2);
    }

    @Test
    public void CreateMetadata(){
        //Set up
        assertEquals(2 ,service.findAllSensorMetadata().size());

        SensorMetadata dbMetadata = service.findMetadataById(METADATA_1.getId());

        assertEquals(METADATA_1,dbMetadata);
    }

    @Test
    public void CreateDataFile(){
        //Set up
        assertEquals(0,service.findAllSensorDataFiles().size());

        //Test
        SensorDataFile cDataFile = new SensorDataFile("Filename", "checkSum", new Date(), new Date(), METADATA_1);
        service.newSensorDataFile(cDataFile);

        //Validate
        assertEquals(1,service.findAllSensorDataFiles().size());

        SensorDataFile dbDatafile = service.findDataFileById(cDataFile.getId());

        assertEquals(cDataFile,dbDatafile);
    }

    @Test
    public void CreateSensorData(){
        //Set up      
        assertEquals(0,service.findAllGreenseekerSensorData().size());

        //Test
        SensorDataFile greenseekerDataFile =
                new SensorDataFile(FILE_NAME_1, FILE_CHECKSUM_1, DATE_CREATED_1, new Date(), METADATA_2);

        GreenseekerSensorData data = new GreenseekerSensorData(
                greenseekerDataFile, OBJECTID_1, LONGITUDE_1, LATITUDE_1, SPEED_1, HEADING_1, ELEVATION_1, NDVI_1, VI_2ND_1, SENSOR_10_1, SENSOR_19_1, SENSOR_23_1, SENSOR_24_1, SENSOR_26_1, SENSOR_73_1);

        service.newSensorDataFile(greenseekerDataFile);
        service.persist(data);

        //Validate
        assertEquals(1,service.findAllGreenseekerSensorData().size());

        GreenseekerSensorData dbSensorData = service.findGreenseekerSensorDataById(data.getId());

        assertEquals(data,dbSensorData);

 
    }

    @Test
    public void testNewInstances() {
        // Setup

        SensorDataFile fileNormal = new SensorDataFile(FILE_NAME_1, FILE_CHECKSUM_1, DATE_CREATED_1, new Date(), METADATA_1);
        SensorDataFile fileBorne = new SensorDataFile(FILE_NAME_2, FILE_CHECKSUM_2, DATE_CREATED_2, new Date(), METADATA_2);

        service.newSensorDataFile(fileNormal);
        service.newSensorDataFile(fileBorne);

        // Test
        GreenseekerSensorData dataNormal = new GreenseekerSensorData(
                fileNormal, OBJECTID_1, LONGITUDE_1, LATITUDE_1, SPEED_1, HEADING_1, ELEVATION_1, NDVI_1, VI_2ND_1, SENSOR_10_1, SENSOR_19_1, SENSOR_23_1, SENSOR_24_1, SENSOR_26_1, SENSOR_73_1);
        GreenseekerSensorData dataBorne = new GreenseekerSensorData(
                fileBorne, OBJECTID_2, LONGITUDE_2, LATITUDE_2, SPEED_2, HEADING_2, ELEVATION_2, NDVI_2, VI_2ND_2,
                RED_53_2, NIR_53_2, RED_54_2, NIR_54_2, RED_55_2, NIR_55_2, RED_56_2, NIR_56_2, RED_57_2, NIR_57_2, RED_58_2, NIR_58_2);

        service.persist(dataNormal);
        service.persist(dataBorne);

        // Verify
        GreenseekerSensorData resultNormal = service.findGreenseekerSensorDataById(dataNormal.getId());
        GreenseekerSensorData resultBorne = service.findGreenseekerSensorDataById(dataBorne.getId());

        assertNotNull(resultNormal);
        assertNotNull(resultBorne);

        // Normal
        assertEquals(fileNormal, resultNormal.getDataSensorFile());
        assertEquals(LONGITUDE_1, resultNormal.getLongitude(), 0.001);
        assertEquals(LATITUDE_1, resultNormal.getLatitude(), 0.001);
        assertEquals(SPEED_1, resultNormal.getSpeed(), 0.001);
        assertEquals(HEADING_1, resultNormal.getHeading(), 0.001);
        assertEquals(ELEVATION_1, resultNormal.getElevation(), 0.001);
        assertEquals(NDVI_1, resultNormal.getNdvi(), 0.001);
        assertEquals(VI_2ND_1, resultNormal.getVi2nd(), 0.001);
        assertEquals(SENSOR_10_1, resultNormal.getSensor10(), 0.001);
        assertEquals(SENSOR_19_1, resultNormal.getSensor19(), 0.001);
        assertEquals(SENSOR_23_1, resultNormal.getSensor23(), 0.001);
        assertEquals(SENSOR_24_1, resultNormal.getSensor24(), 0.001);
        assertEquals(SENSOR_26_1, resultNormal.getSensor26(), 0.001);
        assertEquals(SENSOR_73_1, resultNormal.getSensor73(), 0.001);

        // Borne
        assertEquals(fileBorne, resultBorne.getDataSensorFile());
        assertEquals(LONGITUDE_2, resultBorne.getLongitude(), 0.001);
        assertEquals(LATITUDE_2, resultBorne.getLatitude(), 0.001);
        assertEquals(SPEED_2, resultBorne.getSpeed(), 0.001);
        assertEquals(HEADING_2, resultBorne.getHeading(), 0.001);
        assertEquals(ELEVATION_2, resultBorne.getElevation(), 0.001);
        assertEquals(NDVI_2, resultBorne.getNdvi(), 0.001);
        assertEquals(VI_2ND_2, resultBorne.getVi2nd(), 0.001);
        assertEquals(RED_53_2, resultBorne.getRed53(), 0.001);
        assertEquals(NIR_53_2, resultBorne.getNir53(), 0.001);
        assertEquals(RED_54_2, resultBorne.getRed54(), 0.001);
        assertEquals(NIR_54_2, resultBorne.getNir54(), 0.001);
        assertEquals(RED_55_2, resultBorne.getRed55(), 0.001);
        assertEquals(NIR_55_2, resultBorne.getNir55(), 0.001);
        assertEquals(RED_56_2, resultBorne.getRed56(), 0.001);
        assertEquals(NIR_56_2, resultBorne.getNir56(), 0.001);
        assertEquals(RED_57_2, resultBorne.getRed57(), 0.001);
        assertEquals(NIR_57_2, resultBorne.getNir57(), 0.001);
        assertEquals(RED_58_2, resultBorne.getRed58(), 0.001);
        assertEquals(NIR_58_2, resultBorne.getNir58(), 0.001);
    }
/*

 TODO: persist ZOU EXCEPTION MOETEN GEVEN?

    @Test(expected = IllegalArgumentException.class)
    public void testNewInstanceWithoutFile() {
        // Setup
        assertEquals(0, service.findAllGreenseekerSensorData().size());

        // Test
        GreenseekerSensorData data = new GreenseekerSensorData(
                null, LONGITUDE_1, LATITUDE_1, SPEED_1, HEADING_1, ELEVATION_1, NDVI_1, VI_2ND_1, SENSOR_10_1, SENSOR_19_1, SENSOR_23_1, SENSOR_24_1, SENSOR_26_1, SENSOR_73_1);

        service.persist(data);       
    }
*/

  @Test
    public void testFindAllGreenSeekerSensorData(){

        SensorDataFile fileNormal = new SensorDataFile(FILE_NAME_1, FILE_CHECKSUM_1, DATE_CREATED_1, new Date(), METADATA_1);
        SensorDataFile fileBorne = new SensorDataFile(FILE_NAME_2, FILE_CHECKSUM_2, DATE_CREATED_2, new Date(), METADATA_2);
        
        service.newSensorDataFile(fileNormal);
        service.newSensorDataFile(fileBorne);

        assertEquals(0, service.findAllGreenseekerSensorData().size());

        // Test
        GreenseekerSensorData dataNormal = new GreenseekerSensorData(
                fileNormal, OBJECTID_1, LONGITUDE_1, LATITUDE_1, SPEED_1, HEADING_1, ELEVATION_1, NDVI_1, VI_2ND_1, SENSOR_10_1, SENSOR_19_1, SENSOR_23_1, SENSOR_24_1, SENSOR_26_1, SENSOR_73_1);
        GreenseekerSensorData dataBorne = new GreenseekerSensorData(
                fileBorne, OBJECTID_2, LONGITUDE_2, LATITUDE_2, SPEED_2, HEADING_2, ELEVATION_2, NDVI_2, VI_2ND_2,
                RED_53_2, NIR_53_2, RED_54_2, NIR_54_2, RED_55_2, NIR_55_2, RED_56_2, NIR_56_2, RED_57_2, NIR_57_2, RED_58_2, NIR_58_2);

        service.persist(dataNormal);
        service.persist(dataBorne);

        // Test
        List<GreenseekerSensorData> data = service.findAllGreenseekerSensorData();

        // Verify
        assertNotNull(data);
        assertEquals("Het aantal opgeslagen sensor records klopt niet.", 2, data.size());
        log.info("Found #" + data.size() + " records");
    }

    // Zinvol?
    @Test
    public void testFindAllGreenSeekerSensorDataWithExistingFile() {

        assertEquals(0, service.findAllGreenseekerSensorData().size());
        SensorDataFile sensorFile = new SensorDataFile(FILE_NAME_1, FILE_CHECKSUM_1, DATE_CREATED_1, new Date(), METADATA_1);
        service.newSensorDataFile(sensorFile);

        // Create BO
        GreenseekerSensorData sensorData = new GreenseekerSensorData(
                sensorFile, OBJECTID_1, LONGITUDE_1, LATITUDE_1, SPEED_1, HEADING_1, ELEVATION_1, NDVI_1, VI_2ND_1, SENSOR_10_1, SENSOR_19_1, SENSOR_23_1, SENSOR_24_1, SENSOR_26_1, SENSOR_73_1);
        service.persist(sensorData);

        // Test
        List<GreenseekerSensorData> data = service.findAllGreenseekerSensorData();

        // Verify
        assertNotNull(data);
        assertEquals("Het aantal opgeslagen sensor records klopt niet.", 1, data.size());
        log.info("Found #" + data.size() + " records");
    }

    /*

    // findGreenseekerSensorDataFileByNameChecksum bestaat niet meer.

    @Test
    public void testGreenSeekerSensorDataFileStorage(){
        assertEquals(0, service.findAllGreenseekerDataFiles().size());

        service.persist(METADATA_1);
        GreenseekerDataFile greenSeekerDataSensorFile = new GreenseekerDataFile(FILE_NAME_1, FILE_CHECKSUM_1, DATE_CREATED_1, new Date(), METADATA_1);

        service.persist(greenSeekerDataSensorFile);

        GreenseekerDataFile bO = service. findGreenseekerSensorDataFileByNameChecksum(FILE_NAME_1, FILE_CHECKSUM_1);
        assertNotNull(bO);

        List<GreenseekerDataFile> data = service.findAllGreenseekerDataFiles();

        assertEquals("Het aantal opgeslagen file records klopt niet.", 1, data.size());

    }

    @Test
    public void testGreenSeekerSensorDataFileMerge(){
        assertEquals(0, service.findAllGreenseekerDataFiles().size());

        service.persist(METADATA_1);
        GreenseekerDataFile greenSeekerDataSensorFile = new GreenseekerDataFile(FILE_NAME_1, FILE_CHECKSUM_1, DATE_CREATED_1, new Date(), METADATA_1);
        service.persist(greenSeekerDataSensorFile);
        Date date = new Date();
        greenSeekerDataSensorFile.setFileRead(date);
        service.persist(greenSeekerDataSensorFile);

        assertEquals(date, greenSeekerDataSensorFile.getFileRead());

        GreenseekerDataFile bO = service.findGreenSeekerSensorDataFileByNameChecksum(FILE_NAME_1, FILE_CHECKSUM_1);
        assertNotNull(bO);

        List<GreenseekerDataFile> data = service.findAllGreenSeekerSensorDataFiles();

        assertEquals("Het aantal opgeslagen file records klopt niet.", 1, data.size());
    }

     */

    /*
    @Test
    public void testSensorMetaDataStorage() {
        GreenseekerMetadata metaData = service.findGreenseekerMetadataById(1);
        assertNotNull(metaData);

        metaData = service.findGreenseekerMetaDataBOByMetadata(FILE_NAME_2, 5);
        assertNotNull(metaData);
    }
     
      //Tests if the sensor metadata wil be updated when a detached sensorMetadata argument is parsed.
    @Test
    public void updateSensorMetadataFindMetadataTest() {
        SensorServiceImpl sensorService = new SensorServiceImpl();

        SensorMetadataBO existing = new SensorMetadataBO("DDMMYYCC.CSV", 5, 3, "","","");
        sensorService.persist(existing);
        SensorMetadataBO metadata = new SensorMetadataBO("MMDDYY.CSV", 3, 3, "","","");
        sensorService.persist(metadata);
        //Do not persist this entity
        GreenSeekerSensorDataFileBO greenSeekerDataSensorFile = new GreenSeekerSensorDataFileBO(FILE_NAME_1, FILE_CHECKSUM_1, new Date(), new Date(), metadata);
        sensorService.persist(greenSeekerDataSensorFile);
        SensorMetadataBO updateMetadata = new SensorMetadataBO("DDMMYYCC.CSV", 5, 3, "","","");

        sensorService.updateSensorMetadata(greenSeekerDataSensorFile, updateMetadata);
        //Verrify
        assertEquals(existing.getSensorMetadataId(), greenSeekerDataSensorFile.getSensorMetadata().getSensorMetadataId());
        assertEquals(existing, greenSeekerDataSensorFile.getSensorMetadata());
        assertEquals(2, sensorService.findAllSensorMetaData().size());

    }

    //Tests if the sensor metadata wil be updated when a detached sensorMetadata argument is parsed. The detached argument is also not
    //present in the database
    @Test
    public void updateSensorMetadataUnableFindMetadataTest() {
        SensorServiceImpl sensorService = new SensorServiceImpl();
        //Setup

        SensorMetadataBO metadata = new SensorMetadataBO("MMDDYY.CSV", 3, 3, "","","");
        sensorService.persist(metadata);
        //Do not persist this entity
        GreenSeekerSensorDataFileBO greenSeekerDataSensorFile = new GreenSeekerSensorDataFileBO(FILE_NAME_1, FILE_CHECKSUM_1, new Date(), new Date(), metadata);
        sensorService.persist(greenSeekerDataSensorFile);
        SensorMetadataBO updateMetadata = new SensorMetadataBO("DDMMYYCC.CSV", 5, 3, "","","");


        sensorService.updateSensorMetadata(greenSeekerDataSensorFile, updateMetadata);
        //Verrify
        assertEquals(updateMetadata.getSensorMetadataId(), greenSeekerDataSensorFile.getSensorMetadata().getSensorMetadataId());
        assertEquals(updateMetadata, greenSeekerDataSensorFile.getSensorMetadata());
        assertEquals(2, sensorService.findAllSensorMetaData().size());
    }
     */


    

}
